package org.webdb.jdbc.impl;

import java.sql.ResultSet;

import org.webdb.jdbc.JDBCColumn;
import org.webdb.jdbc.JDBCExecutionContext;
import org.webdb.jdbc.JDBCSqlProvider;
import org.webdb.jdbc.JDBCTable;

import com.healthmarketscience.sqlbuilder.InsertQuery;
import com.healthmarketscience.sqlbuilder.SqlObject;
import com.healthmarketscience.sqlbuilder.dbspec.Column;
import com.healthmarketscience.sqlbuilder.dbspec.Table;
import com.healthmarketscience.sqlbuilder.dbspec.basic.DbSchema;
import com.healthmarketscience.sqlbuilder.dbspec.basic.DbSpec;
import com.healthmarketscience.sqlbuilder.dbspec.basic.DbTable;

public abstract class JDBCAbstractSqlProvider implements JDBCSqlProvider {

    private DbSpec dbSpec;

    public Column column(JDBCTable table, String columnName) {
        JDBCColumn column = table.getColumn(columnName);

        return column(table.getSchema(), table.getName(), column);
    }

    private Column column(String schemaName, String tableName, JDBCColumn column) {
        // TODO Auto-generated method stub
        DbSpec dbSpec = getDbSpec();
        DbSchema dbSchema = dbSpec.findSchema(schemaName);
        if (dbSchema == null)
            dbSchema = dbSpec.addSchema(schemaName);

        DbTable dbTable = dbSchema.findTable(tableName);
        if (dbTable == null)
            dbTable = dbSchema.addTable(tableName);

        Column dbColumn = dbTable.findColumn(column.getName());
        if (dbColumn == null)
            dbColumn = dbTable.addColumn(column.getName(),
                    column.getTypeName(), 0);

        return dbColumn;
    }

    private DbSchema createDbSchema(JDBCTable table) {
        DbSchema dbSchema = getDbSpec().findSchema(table.getSchema());
        if (dbSchema == null) {
            dbSchema = getDbSpec().addSchema(table.getSchema());
        }

        return dbSchema;
    }

    protected abstract DbSpec createDbSpec();

    private DbTable createDbTable(JDBCTable table) {
        DbSchema dbSchema = createDbSchema(table);
        DbTable dbTable = dbSchema.findTable(table.getName());
        if (dbTable == null) {
            dbTable = dbSchema.addTable(table.getName());
        }
        return dbTable;
    }

    public abstract InsertQuery createInsertQuery(Table table);

    protected abstract JDBCSelectQuery createSelectQuery();

    public JDBCExecutionContext execute(SqlObject sqlObject) {
        // TODO Auto-generated method stub
        throw new UnsupportedOperationException();
    }

    public ResultSet executeQuery(SqlObject sqlObject) {
        // TODO Auto-generated method stub
        throw new UnsupportedOperationException();
    }

    public Column getColumn(JDBCColumn column) {
        return column(column.getSchema(), column.getTable(), column);
    }

    private DbSpec getDbSpec() {
        if (dbSpec == null)
            dbSpec = createDbSpec();

        return dbSpec;
    }

    public Table getTable(JDBCTable table) {
        return createDbTable(table);
    }

    public InsertQuery insertInto(JDBCTable table) {
        InsertQuery insertQuery = createInsertQuery(createDbTable(table));
        return insertQuery;
    }

    public JDBCSelectQuery select(JDBCTable table) {
        JDBCSelectQuery selectQuery = createSelectQuery();
        selectQuery.addFromTable(createDbTable(table));
        return selectQuery;
    }
}
